package com.gxc.dbcore.service;

import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.gxc.dbcore.cache.EntityCache;
import com.gxc.dbcore.dao.SqlDao;
import com.gxc.dbcore.util.BeanMap;
import com.gxc.dbcore.util.CompareItem;
import com.gxc.dbcore.util.CompareType;
import com.gxc.dbcore.util.ConditionUtil;
import com.gxc.dbcore.util.EntityDef;
import com.gxc.dbcore.util.PageInfo;
import com.gxc.dbcore.util.PageList;
import com.gxc.webcore.util.MapUtil;

public class BaseService<T> {

	private Class<?> clazz;
	private SqlDao sqlDao;

	public SqlDao getSqlDao() {
		return sqlDao;
	}

	public void setSqlDao(SqlDao sqlDao) {
		this.sqlDao = sqlDao;
	}

	/**
	 * 获取T在实例中的类型
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Class<?> getTClass() {
		if (clazz == null) {
			clazz = (Class<T>) ((ParameterizedType) getClass()
					.getGenericSuperclass()).getActualTypeArguments()[0];
		}
		return clazz;
	}

	/**
	 * 获取一条记录
	 * 
	 * @param idValue
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public T get(Object idValue) {
		EntityDef entityDef = EntityCache.getEntityDef(this.getTClass());
		Map params = new HashMap();
		params.put("schema", entityDef.getSchema());
		params.put("table", entityDef.getTable());
		params.put("columns", entityDef.getProperties());
		params.put("id", entityDef.getId());
		params.put("idValue", idValue);
		BeanMap beanMap = sqlDao.selectOne("webcore.entity.get", params);
		return (T) MapUtil.map2bean(beanMap, clazz);
	}

	/**
	 * 创建一条记录
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public int create(T object) {
		EntityDef entityDef = EntityCache.getEntityDef(this.getTClass());
		Map params = new HashMap();
		params.put("schema", entityDef.getSchema());
		params.put("table", entityDef.getTable());
		params.put("columnList", entityDef.getKeyValueList(object));
		return sqlDao.insert("webcore.entity.create", params);
	}

	/**
	 * 更新一条记录
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public int update(Object object) {
		EntityDef entityDef = EntityCache.getEntityDef(this.getTClass());
		Map params = new HashMap();
		params.put("schema", entityDef.getSchema());
		params.put("table", entityDef.getTable());
		params.put("id", entityDef.getId());
		params.put("idValue", entityDef.getIdValue(object));
		params.put("columnList", entityDef.getKeyValueList(object));
		return sqlDao.update("webcore.entity.update", params);
	}

	/**
	 * 删除一条记录
	 * 
	 * @param idValue
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public int delete(Object idValue) {
		EntityDef entityDef = EntityCache.getEntityDef(this.getTClass());
		Map params = new HashMap();
		params.put("schema", entityDef.getSchema());
		params.put("table", entityDef.getTable());
		params.put("columns", entityDef.getProperties());
		params.put("id", entityDef.getId());
		params.put("idValue", idValue);
		return sqlDao.delete("webcore.entity.delete", params);
	}

	/**
	 * 删除多条记录
	 * 
	 * @param idValueArray
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public int delete(Object[] idValueArray) {
		EntityDef entityDef = EntityCache.getEntityDef(this.getTClass());
		Map params = new HashMap();
		params.put("schema", entityDef.getSchema());
		params.put("table", entityDef.getTable());
		params.put("columns", entityDef.getProperties());
		params.put("id", entityDef.getId());
		params.put("idValueArray", idValueArray);
		return sqlDao.delete("webcore.entity.deleteBatch", params);
	}

	/**
	 * 获取符合条件的记录数
	 * 
	 * @param conditionList
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public long count(List<CompareItem> conditionList) {
		EntityDef entityDef = EntityCache.getEntityDef(this.getTClass());
		Map queryParams = new HashMap();
		queryParams.put("schema", entityDef.getSchema());
		queryParams.put("table", entityDef.getTable());
		queryParams.put("conditionList", conditionList);
		if (conditionList != null) {
			int conditionNum = 0;
			for (CompareItem item : conditionList) {
				if (item.getCompareValue() != null) {
					conditionNum++;
				}
			}
			queryParams.put("conditionNum", conditionNum);
		}
		return sqlDao.selectOne("webcore.entity.count", queryParams);
	}

	/**
	 * 获取符合条件记录
	 * 
	 * @param conditionList
	 * @param fieldSort
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List list(List<CompareItem> conditionList, String fieldSort) {
		EntityDef entityDef = EntityCache.getEntityDef(clazz);
		Map queryParams = new HashMap();
		queryParams.put("schema", entityDef.getSchema());
		queryParams.put("table", entityDef.getTable());
		queryParams.put("columns", entityDef.getProperties());
		queryParams.put("conditionList", conditionList);
		queryParams.put("fieldSort", fieldSort);
		List resultList = sqlDao.selectList("webcore.entity.list", queryParams);
		return MapUtil.maplist2beanlist(resultList, clazz);

	}

	/**
	 * 获取符合条件的记录(分页)
	 * 
	 * @param conditionList
	 * @param fieldSort
	 * @param pageInfo
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public PageList listPage(List<CompareItem> conditionList, String fieldSort,
			PageInfo pageInfo) {

		EntityDef entityDef = EntityCache.getEntityDef(clazz);
		Map queryParams = new HashMap();
		queryParams.put("schema", entityDef.getSchema());
		queryParams.put("table", entityDef.getTable());
		queryParams.put("columns", entityDef.getProperties());
		queryParams.put("conditionList", conditionList);
		queryParams.put("fieldSort", fieldSort);
		if (conditionList != null) {
			int conditionNum = 0;
			for (CompareItem item : conditionList) {
				if (item.getCompareValue() != null) {
					conditionNum++;
				}
			}
			queryParams.put("conditionNum", conditionNum);
		}
		PageList pageList = sqlDao.selectPageList("webcore.entity.list",
				"webcore.entity.count", queryParams, pageInfo);
		pageList.setList(MapUtil.maplist2beanlist(pageList.getList(), clazz));
		return pageList;
	}

	/**
	 * 构建查询条件，建议在子类中重写覆盖此方法
	 * 
	 * @param params
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	protected List<CompareItem> buildConditions(Map params) {
		EntityDef entityDef = EntityCache.getEntityDef(this.getTClass());
		List<CompareItem> conditionList = new ArrayList<CompareItem>();
		conditionList
				.add(new CompareItem(entityDef.getId(), CompareType.EQUAL));
		return ConditionUtil.setConditionValue(conditionList, params);
	}

	/**
	 * 获取符合条件的记录数
	 * 
	 * @param params
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Long count(Map params) {
		List<CompareItem> conditionList = this.buildConditions(params);
		return this.count(conditionList);
	}

	/**
	 * 获取符合条件记录
	 * 
	 * @param params
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<T> list(Map params) {
		List<CompareItem> conditionList = this.buildConditions(params);
		String fieldSort = ConditionUtil.getFieldSort(params);
		return this.list(conditionList, fieldSort);
	}

	/**
	 * 获取符合条件的记录(分页)
	 * 
	 * @param params
	 * @param pageInfo
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public PageList listPage(Map params, PageInfo pageInfo) {
		List<CompareItem> conditionList = this.buildConditions(params);
		String fieldSort = ConditionUtil.getFieldSort(params);
		return this.listPage(conditionList, fieldSort, pageInfo);
	}

}
